<template>
  <div class="jeesite-bpm-trace">
    <div class="box-model" v-show="false">
      <div class="box-title">
        <span>{{ t('图例') }} :</span>
        <span style="color: #017501">
          <Icon icon="i-ant-design:check-circle-outlined" style="padding: 5px" />
          {{ t('已完成') }}
        </span>
        <span style="color: #e90606">
          <Icon icon="i-ant-design:clock-circle-outlined" style="padding: 5px" />
          {{ t('进行中') }}
        </span>
        <span style="color: #585858">
          <Icon icon="i-ant-design:minus-circle-outlined" style="padding: 5px" />
          {{ t('未执行') }}
        </span>
      </div>
      <div class="box-tool" v-if="message">{{ message }}</div>
      <div ref="navTree" class="box-tool nav-tree" :data-text-main-process="t('主流程')"></div>
      <div ref="bpmnModel" style="overflow: auto" @click="_closeTip"></div>
    </div>
    <div class="box-timeline">
      <FormGroup>{{ t('流转信息') }}</FormGroup>
      <div class="process-timeline">
        <div 
          v-for="(item, index) in timelineData" 
          :key="index" 
          class="timeline-item"
          :class="{ 'timeline-item-completed': item.status === '已完成', 'timeline-item-active': item.status === '进行中' }"
        >
          <div class="timeline-dot">
          </div>
              <div 
            class="timeline-connector-segment" 
            :class="{ 'last-segment': index === timelineData.length - 1 }"
            v-if="index < timelineData.length - 1"
          ></div>

          <div class="timeline-content">
            <div class="timeline-header">
              <div class="timeline-title">
                {{ item.name || t('未设置环节名') }}
                <div class="child-toggle" v-show=" item.children.length!== 0" @click="toggleChildren(index)" style="">
                  <Icon 
                    :icon="expandedIndex === index ? 'i-ant-design:up-outlined' : 'i-ant-design:down-outlined'" 
                    class="toggle-icon" 
                  />
                  {{ expandedIndex === index ? t('收起') : t('展开') }}
                  <span class="child-count">({{ item.children.length }})</span>
                </div>
              </div>
              <div style="display: flex; justify-content:start; align-items: center;">
                <div class="timeline-time">
                  创建:{{ item.createTime|| '无' }}
                </div>
                <div class="timeline-time">
                  完成:{{ item.endTime || '无' }}
                </div>
                <!-- <div class="timeline-details"> -->
                <div class="detail-row">
                  <span class="detail-value">{{ t('历时') }}:{{ item.durationFormat || '无' }}</span>
                </div>
                <div class="detail-row">
                  <span  class="detail-value" >{{ item.assigneeInfo || '处理人:无' }}</span>
                </div>
                <div class="detail-row">
                  <span  
                  class="detail-value"  
                  ref="tooltipRef" 
                  @mouseenter="showTooltip($event, item.comment)" 
                  @mouseleave="hideTooltip"
                  style="overflow: hidden;text-overflow: ellipsis;white-space: nowrap;max-width: 250px;"
                  >
                  审批意见： {{ item.comment || '无' }}
                  </span>
                  <div 
                    class="tooltip" 
                    v-show="isTooltipVisible" 
                    :style="{ top: tooltipY + 'px', left: tooltipX + 'px' }"
                  >
                    {{ tooltipContent }}
                  </div>
                </div>
                <!-- </div> -->
             </div>
            
            </div>
            <!-- 子时间轴数据展示 -->
            <div v-if="item.children && item.children.length > 0" class="child-timeline-container">
               <div class="child-toggle" @click="toggleChildren(index)" style="display: none;">
                <!-- 隐藏原位置的展开收起按钮 -->
              </div>
              <div v-show="expandedIndex === index" class="child-timeline">
                <div 
                  v-for="(childItem, cIndex) in item.children" 
                  :key="cIndex" 
                  class="child-item"
                >
                  <div class="child-dot"></div>
                  <div class="child-content">
                      <div class="child-title">
                        <span style="margin-right:15px;">{{ childItem.notifierName }}</span> <span style="font-weight: 400;">{{ childItem.createTime }} </span>
                      </div>
                      <div class="child-linkageLevel">  {{ childItem.linkageLevel }}</div>
                     <div class="child-details">
                      <div class="child-message">通知内容: {{ childItem.notifierContent }}</div>
                     </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script lang="ts" name="BpmRuntimeTraceTimeLine">
import { defineComponent } from 'vue';

export default defineComponent({
  name: 'JeeSiteBpmRuntimeTrace',
  inheritAttrs: false,
});
</script>

<script lang="ts" setup>
import { defineComponent, ref, defineProps, toRefs, computed, onUnmounted, watch } from 'vue';
import { useI18n } from '/@/hooks/web/useI18n';
import { BasicTable, useTable } from '/@/components/Table';
import { FormGroup } from '/@/components/Form';
import { Icon } from '/@/components/Icon';
import {
  bpmTrace,
  bpmProcDefModel,
  bpmProcInsModel,
  bpmProcInsHistoryModel,
  bpmProcInsTrace,
} from '/@/api/bpm';
import { _showProcessDiagram, _closeTip } from './js/displaymodel.js';
import { InFireNotificationData } from '/@/api/management/inFireNotification';

const { t } = useI18n('bpm.button');

const message = ref();
const historyProcInsId = ref('');
const procInsId = ref('');
const procDefId = ref('');
const tableDataSource = ref<Recordable[]>([]);
const traceName = ref('');
const tableName = ref('');
const navTree = ref();
const bpmnModel = ref();
const traceStatus = ref([]);
const ChildrenDataSource = ref();
const expandedIndex = ref(-1); // 当前展开的子流程索引

// 子表列定义
const childTableColumns = ref([
  {
    title: t('通知人'),
    dataIndex: 'notifierName',
    width: 100,
  },
  {
    title: t('通知情况'),
    dataIndex: 'linkageLevel',
    width: 100,
  },
  {
    title: t('通知内容'),
    dataIndex: 'notifierContent',
    width: 100,
  },
  {
    title: t('通知时间'),
    dataIndex: 'createTime',
    width: 100,
  },
]);

const props = defineProps({
  maintainTaskId: {
    type: String,
    default: '',
  },
  formKey: {
    type: String,
    default: '',
  },
  bizKey: {
    type: String,
    default: '',
  },
});

const MaintainceBpmTaskId = ref('');
const TableDataSource2 = ref('');
const endRowName = ref('');

// 计算属性，根据TableDataSource2.value是否存在来决定数据源
const resolvedDataSource = computed(() => {
  return TableDataSource2.value || tableDataSource.value;
});

// 时间轴数据
const timelineData = computed(() => {
  return resolvedDataSource.value.map(item => {
    let statusText = '';
    if (item.status === '2') {
      statusText = '已完成';
    } else if (item.status === '1') {
      statusText = '进行中';
    } else {
      statusText = '未执行';
    }
    
    // 处理子流程数据
    const children = item.children?.map(child => {
      // 根据通知情况判断状态
      let childStatus = '已完成';
      if (child.linkageLevel.includes('待')) {
        childStatus = '进行中';
      }
      
      return {
        ...child,
        status: childStatus
      };
    });
    
    return {
      ...item,
      status: statusText,
      statusColor: item.status === '2' ? '#017501' : item.status === '1' ? '#e90606' : '#585858',
      children: children || []
    };
  });
});

// 切换子流程展开状态
function toggleChildren(index: number) {
  expandedIndex.value = expandedIndex.value === index ? -1 : index;
}

function removeDecimalPart(str) {
  // 查找字符串中最后一个 '秒' 字的位置
  const secondsIndex = str.lastIndexOf('秒');
  if (secondsIndex > -1) {
    // 截取 '秒' 字之前的部分
    const beforeSeconds = str.slice(0, secondsIndex);
    // 找到小数点位置
    const dotIndex = beforeSeconds.lastIndexOf('.');
    if (dotIndex > -1) {
      // 去掉小数点及其后面的内容
      return beforeSeconds.slice(0, dotIndex) + '秒';
    }
  }
  return str;
}

async function showProcessDiagram(bizKey) {
  let data: any = {};
  if (historyProcInsId.value && historyProcInsId.value !== '') {
    data = await bpmProcInsHistoryModel({ id: historyProcInsId.value });
    tableDataSource.value = await bpmProcInsTrace({ id: historyProcInsId.value });
    console.log('tableDataSourceHistory:', tableDataSource.value)
    traceName.value =
      (tableDataSource.value[1]?.procIns?.procDef?.id) ||
      (tableDataSource.value[0]?.procIns?.procDef?.id);
    // 获取数组最后一个元素
    const lastItem =
      tableDataSource.value.length > 0
        ? tableDataSource.value[tableDataSource.value.length - 1]
        : null;
    traceStatus.value = lastItem?.status;
  } else if (procInsId.value && procInsId.value !== '') {
    data = await bpmProcInsModel({ id: procInsId.value });
    tableDataSource.value = await bpmProcInsTrace({ id: procInsId.value });
    console.log('tableDataSource:', tableDataSource.value)
    traceName.value =
      (tableDataSource.value[1]?.procIns?.procDef?.id) ||
      (tableDataSource.value[0]?.procIns?.procDef?.id);
    // 获取数组最后一个元素
    const lastItem =
      tableDataSource.value.length > 0
        ? tableDataSource.value[tableDataSource.value.length - 1]
        : null;
    traceStatus.value = lastItem?.status;
  } else if (procDefId.value && procDefId.value !== '') {
    data = await bpmProcDefModel({ id: procDefId.value });
  }
  if (data.message) {
    message.value = data.message;
    return;
  }
  tableDataSource.value.forEach((item) => {
    if (item.durationFormat) {
      // //console.log(item.durationFormat);
    }
  });
  // 根据traceName的值设置tableName
  if (traceName.value && typeof traceName.value === 'string') {
    if (traceName.value.includes('maintenance_process')) {
      tableName.value = '维保工单流程';
      if (bizKey) {
        const res = await InFireNotificationData({ mainId: bizKey });
        ChildrenDataSource.value = res.list || []; // 赋值响应式变量
        // 手动触发主表 reload（若响应式未自动生效）
        console.log('请求接口InFireNotificationData的结果:', ChildrenDataSource.value);
        const sortedChildren = (res.list || []).sort((a, b) => {
          return new Date(a.createTime).getTime() - new Date(b.createTime).getTime();
        });
        ChildrenDataSource.value = sortedChildren;

        // 筛选子表数据并添加到对应的父表记录中
        tableDataSource.value.forEach((item, index) => {
          const prevEndTime = index > 0 ? tableDataSource.value[index - 1].endTime : null;
          const currentEndTime = item.endTime;
          item.children = sortedChildren.filter(child => {
            const childCreateTime = new Date(child.createTime);
            if (prevEndTime) {
              const prevEnd = new Date(prevEndTime);
              return childCreateTime > prevEnd && (currentEndTime ? childCreateTime < new Date(currentEndTime) : true);
            } else {
              return currentEndTime ? childCreateTime < new Date(currentEndTime) : true;
            }
          });
        });
      }
    } else if (traceName.value.includes('supervisor_approval_process')) {
      tableName.value = '监督员审批流程';
    } else if (traceName.value.includes('equipment_fire_warning_process')) {
      tableName.value = '设备火情预警流程';
      // 新增逻辑：请求接口InFireNotificationData
      if (bizKey) {
        const res = await InFireNotificationData({ mainId: bizKey });
        ChildrenDataSource.value = res.list || []; // 赋值响应式变量
        // 手动触发主表 reload（若响应式未自动生效）
        console.log('请求接口InFireNotificationData的结果:', ChildrenDataSource.value);
        const sortedChildren = (res.list || []).sort((a, b) => {
          return new Date(a.createTime).getTime() - new Date(b.createTime).getTime();
        });
        ChildrenDataSource.value = sortedChildren;

        // 筛选子表数据并添加到对应的父表记录中
        const noticeData = ChildrenDataSource.value.filter(item => item.linkageLevel.includes('确认'));
        const disposeData = ChildrenDataSource.value.filter(item => item.linkageLevel.includes('处置'));

        const confirmRow = tableDataSource.value.find(item => item.name === '负责人确认收到预警');
        const disposeRow = tableDataSource.value.find(item => item.name === '负责人处置预警');

        if (confirmRow) {
          confirmRow.children = noticeData;
        }
        if (disposeRow) {
          disposeRow.children = disposeData;
        }
      }
    } else if (traceName.value.includes('Equipment_Failure_Process')) {
      tableName.value = '设备故障流程';
    } else if (traceName.value.includes('Fire_Hazard_Process')) {
       tableName.value = '消防隐患流程';
       // 新增逻辑：请求接口InFireNotificationData
      if (bizKey) {
        const res = await InFireNotificationData({ mainId: bizKey });
        ChildrenDataSource.value = res.list || []; // 赋值响应式变量
        // 手动触发主表 reload（若响应式未自动生效）
        console.log('请求接口InFireNotificationData的结果:', ChildrenDataSource.value);
        const sortedChildren = (res.list || []).sort((a, b) => {
          return new Date(a.createTime).getTime() - new Date(b.createTime).getTime();
        });
        ChildrenDataSource.value = sortedChildren;

        // 筛选子表数据并添加到对应的父表记录中
        tableDataSource.value.forEach((item, index) => {
          const prevEndTime = index > 0 ? tableDataSource.value[index - 1].endTime : null;
          const currentEndTime = item.endTime;
          item.children = sortedChildren.filter(child => {
            const childCreateTime = new Date(child.createTime);
            if (prevEndTime) {
              const prevEnd = new Date(prevEndTime);
              return childCreateTime > prevEnd && (currentEndTime ? childCreateTime < new Date(currentEndTime) : true);
            } else {
              return currentEndTime ? childCreateTime < new Date(currentEndTime) : true;
            }
          });
        });
      }
    } else if (traceName.value.includes('leave')) {
      tableName.value = '请假流程';
    } else {
      tableName.value = '';
    }
  }

  // 处理任务历时数据
  tableDataSource.value.forEach((item) => {
    if (item.durationFormat) {
      // 如果字符串包含 '毫秒'，将其替换为 '1秒'
      if (item.durationFormat.includes('毫秒')) {
        item.durationFormat = '1秒';
      } else {
        // 去掉小数点及其后面的内容
        item.durationFormat = removeDecimalPart(item.durationFormat);
      }
    }
  });

  //console.log('tableDataSource:', tableDataSource.value);

  // 在表格第一行增加一行xx流程开始
  const nextRowCreateTime =
    tableDataSource.value.length > 0
      ? tableDataSource.value[0].createTime
      : '';
  const startRow = {
    name: `${tableName.value}开始`,
    createTime: nextRowCreateTime,
    endTime: '',
    durationFormat: '',
    assigneeInfo: '',
    comment: '',
    status: '已完成'
  };
  tableDataSource.value.unshift(startRow);

  // 在表格最后一行增加一行xx流程结束（根据条件判断是否添加）
  if (traceStatus.value === '2') {
    const prevRowEndTime =
      tableDataSource.value.length > 0
        ? tableDataSource.value[tableDataSource.value.length - 1].endTime
        : '';
     endRowName.value = `${tableName.value}结束`;
     console.log('endRowName:', endRowName.value)
    const endRow = {
      name: endRowName.value,
      createTime: '',
      endTime: prevRowEndTime,
      durationFormat: '',
      assigneeInfo: '',
      comment: '',
      status: '已完成'
    };
    tableDataSource.value.push(endRow);
  }
  
  _showProcessDiagram(
    data,
    bpmnModel.value,
    navTree.value,
    tableDataSource.value
  );
}

// 移除模态框相关逻辑，直接调用数据加载方法
watch(() => [props.formKey, props.bizKey], async () => {
  if (props.formKey && props.bizKey) {
    const res = await bpmTrace({ formKey: props.formKey, bizKey: props.bizKey });
    const data = res.params || {};
    if (data.status === '1') {
      historyProcInsId.value = '';
      procInsId.value = data.id;
    } else {
      historyProcInsId.value = data.id;
      procInsId.value = '';
    }
    procDefId.value = data.procDef?.id;
    // 确保 tableDataSource.value 有数据
    await showProcessDiagram(props.bizKey);

    if (props.formKey === 'Fire_Hazard_Process' && props.maintainTaskId) {
      console.log('props.maintainTaskId:', props.maintainTaskId);
      endRowName.value = '转维保工单'
      console.log('props.maintainTaskId:', props.maintainTaskId,endRowName.value);
      const newRes = await bpmTrace({
        formKey: 'maintenance_process',
        bizKey: props.maintainTaskId,
      });
      // console.log('二次调用 bpmTrace的id 结果:', newRes.bpmProcIns.id);
      // 不更新data变量，避免影响表格数据
      MaintainceBpmTaskId.value = newRes.bpmProcIns.id;

      if (MaintainceBpmTaskId.value) {
        const secondResult = await bpmProcInsTrace({
          id: MaintainceBpmTaskId.value,
        });
        console.log('二次调用 bpmTrace的id 结果:', secondResult);

        const processedSecondResult = secondResult.map(item => {
            if (item.durationFormat) {
              item.durationFormat = removeDecimalPart(item.durationFormat); // 调用已有函数
            }
            return item;
          });

        //console.log('二次调用 bpmProcInsTrace的结果:', secondResult);
        // 将 secondResult 数组内对象元素转为 Proxy(Object)
        const proxiedSecondResult = secondResult.map((obj) => {
          return new Proxy(obj, {
            get(target, property) {
              return target[property];
            },
            set(target, property, value) {
              target[property] = value;
              return true;
            },
          });
        });
        // 合并数据
        TableDataSource2.value = [...tableDataSource.value, ...proxiedSecondResult];
        console.log('tableDataSource2:', TableDataSource2.value);
      }
    }
  }
}, { immediate: true });

const isTooltipVisible = ref(false); // 悬浮窗显示状态
const tooltipContent = ref(''); // 悬浮窗内容
const tooltipX = ref(0); // 悬浮窗X坐标
const tooltipY = ref(0); // 悬浮窗Y坐标

// 显示悬浮窗
function showTooltip(event: MouseEvent, content: string) {
  if (!content) return; // 无内容时不显示
  tooltipContent.value = content;
  
  // 获取鼠标位置并调整悬浮窗位置
  const rect = (event.target as HTMLElement).getBoundingClientRect();
  tooltipX.value = event.clientX + 10; // 鼠标右侧10px
  tooltipY.value = event.clientY + 10; // 鼠标下方10px

  // 防止悬浮窗超出浏览器窗口
  const maxX = window.innerWidth - tooltipX.value;
  const maxY = window.innerHeight - tooltipY.value;
  if (maxX < 100) tooltipX.value = event.clientX - 110; // 左侧显示
  if (maxY < 50) tooltipY.value = event.clientY - 60; // 上方显示

  isTooltipVisible.value = true;
}

// 隐藏悬浮窗
function hideTooltip() {
  isTooltipVisible.value = false;
}
</script>

<style scoped lang="less">
.jeesite-bpm-trace {
  position: relative;

  .box-model {
    text-align: center; 

    .box-title {
      padding: 5px;
      margin-bottom: 5px;
      font-weight: bold;

      span {
        padding-right: 5px;
      }
    }

    .box-tool {
      margin-top: 20px;
    }

    .nav-tree a {
      white-space: normal;
      word-break: break-all;
    }

    svg {
      display: inline-block;
    }
  }

  .box-timeline {
    margin-top: 20px;
    
    .process-timeline {
      position: relative;
      margin-left: 40px;
      padding: 10px 0;
      
      .timeline-connector-segment {
        position: absolute;
        left: -16px;
        width: 2px;
        background-color: #2F51FF;
        z-index: 1;
        // 根据需要调整上下间距
        top: 18px; 
        bottom: -20px; 
      }
      
      .timeline-item {
        position: relative;
        margin-bottom: 25px;
        padding-left: 20px;
        
        .timeline-dot {
          position: absolute;
          left: -20.5px;
          top: 0;
          width: 12px;
          height: 12px;
          background-color: #2F51FF; 
          border-radius: 50%;
          border-radius: 50%;
          display: flex;
          align-items: center;
          justify-content: center;
          z-index: 2;
        }
        
        .timeline-content {
          background-color: #ffffff;
          border-radius: 6px;
          padding: 12px 16px;
          transition: all 0.3s ease;
          
          .timeline-header {
            display: flex;
            flex-direction: column;
            margin-bottom: 8px;
            
            .timeline-title {
              font-size: 16px;
              font-weight: 500;
              margin-bottom: 4px;
              display: flex;
              align-items: center;
              justify-content: start;
              .child-toggle {
                color: #3b82f6;
                cursor: pointer;
                font-size: 13px;
                display: flex;
                align-items: center;
                margin-left: 10px;
                
                .toggle-icon {
                  margin-right: 5px;
                }
                
                .child-count {
                  margin-left: 5px;
                  color: #3b82f6;
                  font-size: 12px;
                }
              }
              
              .timeline-status {
                margin-left: 10px;
                font-size: 14px;
                font-weight: normal;
              }
            }
            
            .timeline-time {
              font-size: 13px;
              color: #6b7280;
              margin-right: 15px;
              white-space: nowrap; /* 禁止文本换行 */
              background-color: #edf0f3;
              padding: 3px 10px;
              // 修改宽度为自动适应内容
              width: auto; 
              text-align: center;
            }
          }
          
          // .timeline-details {
          //   font-size: 13px;
          //   color: #4b5563;
          //   display: flex;
          //   justify-content: start;
          //   align-items: center;
            
            .detail-row {
              display: flex;
              margin-right: 15px;
              text-align: center;
              white-space: nowrap; /* 禁止文本换行 */
              background-color: #edf0f3;
              color: #4b5563;
              padding: 3px 10px;
              // 修改宽度为自动适应内容
              width: auto;     
              .detail-value {
                font-size: 13px;
                white-space: nowrap; /* 禁止文本换行 */
                width: auto;
              }
              .tooltip {
                position: fixed;
                padding: 8px 12px;
                background-color: rgba(33, 33, 33, 0.9);
                color: white;
                border-radius: 4px;
                font-size: 14px;
                line-height: 1.4;
                white-space: pre-wrap; /* 保留换行 */
                max-width: 300px; /* 最大宽度 */
                box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
                pointer-events: none; /* 鼠标穿透，避免遮挡事件 */
              }
            }
          
          .child-timeline-container {
            border-top: 1px solid #f3f4f6;
            
            .child-toggle {
              color: #3b82f6;
              cursor: pointer;
              font-size: 13px;
              display: flex;
              align-items: center;
              
              .toggle-icon {
                margin-right: 5px;
              }
              
              .child-count {
                margin-left: 5px;
                color: #6b7280;
                font-size: 12px;
              }
            }
            
            .child-timeline {
              position: relative;
              margin-top: 15px;
              margin-left:0;
              padding: 0;
              
              .child-item {
                position: relative;
                margin-bottom: 15px;
                padding-left: 15px;
                
                .child-dot {
                  position: absolute;
                  left: 5px;
                  top: 15px;
                  width: 10px;
                  height: 10px;
                  border-radius: 50%;
                  // 将背景颜色设置为透明
                  background-color: transparent;
                  // 设置边框样式和颜色
                  border: 2px solid #3b82f6;
                  z-index: 2;
                }
                
                .child-content {
                  // background-color: #f8fafc;
                  border-radius: 4px;
                  padding: 8px 12px;
                  font-size: 14px;
                  
                    .child-title {
                      font-weight: 500;
                      color: #334155;
                       margin-bottom: 8px
                    }
                    
                    .child-linkageLevel {
                      font-size: 14px;
                      color: #475569;
                      margin-bottom: 8px
                    }
                  
                  .child-details {
                    .child-message {
                      color: #475569;
                      margin-bottom: 8px
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
</style>